package com.mew.chess.core.game.lh.game.task;


import com.mew.chess.core.common.handler.ChessPushMessageUtil;
import com.mew.chess.core.common.message.response.ChipMessage;
import com.mew.chess.core.common.provide.GameFeignService;
import com.mew.chess.core.common.utils.ChessGameUtil;
import com.mew.chess.core.game.lh.game.LhGameManager;
import com.mew.chess.core.game.lh.game.LhRoomManager;
import com.mew.chess.core.game.lh.game.common.LhConstantValue;
import com.mew.chess.core.game.lh.game.common.LhLinkType;
import com.mew.chess.core.game.lh.game.core.LhGame;
import com.mew.chess.core.game.lh.game.message.LhDealCardMessage;
import com.mew.chess.core.game.lh.game.message.LhPaymentMessage;
import com.mew.chess.core.game.lh.game.message.LhPushCMDMapType;
import com.mew.chess.core.game.lh.game.message.LhUserMessage;
import com.mew.common.dc.redis.AucRedisService;
import com.mew.common.dc.redis.GameRoomRedisService;
import com.mew.common.enm.StrategyType;
import com.mew.common.enm.UserType;
import com.mew.common.entity.config.Room;
import com.mew.common.rest.bo.MewSession;
import com.mew.common.rest.game.BetAfterRequest;
import com.zebra.common.OnlineType;
import com.zebra.common.concurrent.ZebraExecutorManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
@Slf4j
public class LhPaymentTask {

    @Autowired
    private AucRedisService aucRedisService;
    @Autowired
    private GameRoomRedisService gameRoomRedisService;
    @Autowired
    private GameFeignService feignService;

    public void payment(int roomId){
        LhRoomManager roomManager = LhGameManager.getInstance().getController(roomId);
        if (!roomManager.getPlayerList().isEmpty()){
            computePayment(roomManager);
            persistenceData(roomManager);
        }

        paymentLinkType(roomManager);
        sendPaymentMsg(roomManager);
    }

    private void paymentLinkType(LhRoomManager roomManager){
        roomManager.setRuleTime(LhConstantValue.PAYMENT);
        roomManager.setLinkType(LhLinkType.Payment.code());
        roomManager.setStartTime(System.currentTimeMillis());
    }

    private void computePayment(LhRoomManager roomManager){

        LhGame lhGame = roomManager.getDealCardMessage().getLhGame();
        roomManager.addHistoryVOList(lhGame.getRes());

        roomManager.getPlayerList().values().stream().collect(Collectors.toList()).forEach(u->doPaymentRecord(lhGame,u));


    }

    private void doPaymentRecord(LhGame lhGame, LhUserMessage userMessage){

        if (userMessage.getBets().size()>0){

            long bet = 0;
            long paymentNumber = 0;

            for (ChipMessage betmsg : userMessage.getBets()) {
                long p = (long)(betmsg.getBetNumber()* lhGame.payment(betmsg.getBetType()));
                paymentNumber+=p;
                bet+=betmsg.getBetNumber();
            }

            userMessage.setBetNumber(bet);
            userMessage.setPaymentNumber(paymentNumber);
        }

    }


    private void persistenceData(LhRoomManager lhRoomManager){
        //local compute
        Collection<LhUserMessage> lhUserMessages = lhRoomManager.getPlayerList().values().stream().filter(u->u.getBets().size()>0).collect(Collectors.toList());
        List<BetAfterRequest> list = new ArrayList<>(lhUserMessages.size());

        Room room = gameRoomRedisService.getRedisRoom(lhRoomManager.getGameId(), lhRoomManager.getRoomId());

        lhUserMessages.forEach(v -> {
            //税 桌费
            v.setBetNumber(v.getBetNumber());
            v.setTax(ChessGameUtil.computeTax(v.getPaymentNumber(), 0));
            v.setPaymentNumber(v.getTax() == 0 ? v.getPaymentNumber() : (v.getPaymentNumber() - v.getTax()));

            BetAfterRequest record = builPlayRecord(lhRoomManager,  v);


            if (UserType.Robot.code()!=v.getUserType()){
                list.add(record);
            }else {
                v.setPlayTimes(1+v.getPlayTimes());
            }

            v.updateGoldNumber(record.getPayment());

        });

        int size = list.size();
        if (size < 30){
            ZebraExecutorManager.getInstance().getDefaultExecutor().execute(() -> {
                feignService.chessBetAfter(list);
            });
            return;
        }


        ZebraExecutorManager.getInstance().getDefaultExecutor().execute(() -> {
            int s = 30;
            int c = (size / s) + 1;
            try {
                for (int i=0; i<c && i*s < size; i++){
                    TimeUnit.MILLISECONDS.sleep(200);
                    List<BetAfterRequest> subList = list.stream().skip(i*s).limit(s).collect(Collectors.toList());
                    feignService.chessBetAfter(subList);
                }
            } catch (InterruptedException e) {
            }
        });

    }

    //TODO
    private BetAfterRequest builPlayRecord(LhRoomManager lhRoomManager, LhUserMessage lhUserMessage){
        long betNumber = lhUserMessage.getBetNumber();
        long paymentNumber = lhUserMessage.getPaymentNumber();

        //lhUserMessage.setPlayer(0); //TODO 参与游戏 解锁

        LhDealCardMessage dealCardMessage = lhRoomManager.getDealCardMessage();

        BetAfterRequest request = BetAfterRequest.builder()
                .uid(lhUserMessage.getUserId())
                .relateInoutId(lhUserMessage.getInoutId())
                .gameId(lhUserMessage.getGameId())
                .roomId(lhUserMessage.getRoomId())
                .bet(betNumber)
                .payment(paymentNumber)
                .rollerId(dealCardMessage.getRollerId())
                .betTimes(paymentNumber < 1 ? 0 : (int) (paymentNumber / betNumber))
                .iconResult(dealCardMessage.lhGame.loong +"-"+ dealCardMessage.lhGame.hu)
                .betArray("")
                .roomRecord(1)
                .paymentArray("")
                .ino(lhRoomManager.getIno())
                .tax(lhUserMessage.getTax())
                .build();

        return request;
    }

    private void sendPaymentMsg(LhRoomManager roomManager){

        roomManager.getOnlineUser().forEach((k, session) -> {

            if (null != session && !session.isWeakClose()){
                LhPaymentMessage paymentMessage = new LhPaymentMessage();
                paymentMessage.setPaymentMap(roomManager.getPaymentMessage().getPaymentMap());
                paymentMessage.setHistoryMessage(roomManager.getHistoryVOList());
                paymentMessage.setBigRList(roomManager.getBigRList());
                LhUserMessage userMessage = roomManager.getPlayer(k);
                paymentMessage.setPaymentNumber(userMessage.getPaymentNumber());
                paymentMessage.setGoldNumber(userMessage.getGoldNumber());

                ChessPushMessageUtil.pushMessage(session,LhPushCMDMapType.PaymentMessage.code(),paymentMessage);

            }else {
                MewSession mewSession = aucRedisService.getSession(k);
                if (mewSession.onl== OnlineType.Online.value()){

                }
            }
        });
    }

}
